﻿using System;
using System.Collections.Generic;
using System.Linq;
using _5E.Utils.MathHelper;

namespace _5E.Utils.CollectionHelper.GenericExtension
{
    /// <summary>
    /// 程序说明：泛型集合扩展类
    /// 创建作者：ahl
    /// 创建时间：2012-03-25
    /// </summary>
    public static class GenericCollectionExtension
    {
        #region List<T>

        #endregion

        #region Dictionary<TKey,TValue>

        /// <summary>
        /// 添加单个键值,会检查键是否存在,如果存在则不添加
        /// </summary>
        /// <typeparam name="TKey">键的类型</typeparam>
        /// <typeparam name="TValue">值的类型</typeparam>
        /// <param name="dic">当前字典</param>
        /// <param name="tKey">添加的键</param>
        /// <param name="tValue">添加的值</param>
        /// <returns></returns>
        public static Dictionary<TKey, TValue> TryAdd<TKey, TValue>(this Dictionary<TKey, TValue> dicSelf, TKey tKey, TValue tValue)
        {
            TValue existValue;
            if (!dicSelf.TryGetValue(tKey, out existValue))
            {
                dicSelf.Add(tKey, tValue);
            }
            return dicSelf;
        }

        /// <summary>
        /// 添加字典,会检查原字典中的键是否存在,如果存在则不进行添加
        /// </summary>
        /// <typeparam name="TKey">键的类型</typeparam>
        /// <typeparam name="TValue">值的类型</typeparam>
        /// <param name="dic">当前字典</param>
        /// <param name="dicOther">要添加的字典</param>
        /// <returns></returns>
        public static Dictionary<TKey, TValue> TryAdd<TKey, TValue>(this Dictionary<TKey, TValue> dicSelf, Dictionary<TKey, TValue> dicOther)
        {
            foreach (var pair in dicOther)
            {
                TryAdd(dicSelf, pair.Key, pair.Value);
            }
            return dicSelf;
        }

        /// <summary>
        /// 添加字典中的列表值，如果键存在对应的列表，则添加相，如果不存在则创建列表
        /// </summary>
        /// <typeparam name="TKey">键的类型</typeparam>
        /// <typeparam name="TValue">值的类型</typeparam>
        /// <param name="dicSelf">当前字典</param>
        /// <param name="tKey">键</param>
        /// <param name="tValue">值对象</param>
        /// <returns></returns>
        public static Dictionary<TKey, List<TValue>> TryAdd<TKey, TValue>(this Dictionary<TKey, List<TValue>> dicSelf, TKey tKey,
            TValue tValue)
        {
            List<TValue> tValueList;
            if (!dicSelf.TryGetValue(tKey, out tValueList))
            {
                tValueList = new List<TValue>();
                dicSelf.Add(tKey, tValueList);
            }
            tValueList.Add(tValue);
            return dicSelf;
        }

        /// <summary>
        /// 添加字典中的字典值
        /// </summary>
        /// <typeparam name="TKey1">父字典键的类型</typeparam>
        /// <typeparam name="TKey2">子字典键的类型</typeparam>
        /// <typeparam name="TValue">值的类型</typeparam>
        /// <param name="dicSelf">当前字典</param>
        /// <param name="tKey1">父字典键</param>
        /// <param name="tKey2">子字典键</param>
        /// <param name="tValue">子字典值对象</param>
        /// <returns></returns>
        public static Dictionary<TKey1, Dictionary<TKey2, TValue>> TryAdd<TKey1, TKey2, TValue>(
            this Dictionary<TKey1, Dictionary<TKey2, TValue>> dicSelf, TKey1 tKey1, TKey2 tKey2, TValue tValue)
        {
            Dictionary<TKey2, TValue> dicChild;
            if (!dicSelf.TryGetValue(tKey1, out dicChild))
            {
                dicChild = new Dictionary<TKey2, TValue>();
                dicSelf.Add(tKey1, dicChild);
            }
            dicChild.Add(tKey2, tValue);
            return dicSelf;
        }

        #endregion

        #region IEnumerable<T>

        public static bool IsNullOrEmpty<T>(this IEnumerable<T> enumList)
        {
            var isNullOrEmpty = null == enumList || 0 == enumList.Count();
            return isNullOrEmpty;
        }

        public static T2 Exchange<T1, T2>(this IEnumerable<T1> enumList, T2 defaultValue)
            where T2 : IEnumerable<T1>
        {
            var isNullOrEmpty = enumList.IsNullOrEmpty();
            return isNullOrEmpty ? defaultValue : (T2)enumList;
        }

        public static T RandomOne<T>(this IEnumerable<T> list)
        {
            var count = list.Count();
            if (0 == count)
            {
                throw new ArgumentException("元素个数必须大于0!");
            }
            var index = RandomHelper.GetRandomInt32(count);
            return list.ElementAt(index);
        }

        #endregion
    }
}
